home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 1999 #3
/
Amiga Plus CD - 1999 - No. 3.iso
/
System
/
dsound
/
source.lha
/
DSound.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-07-18
|
28KB
|
1,051 lines
/**************************************************************************/
/* DSound V1.50 */
/* Copyright 1991-1994 by Dave Schreiber, All Rights Reserved. */
/* */
/* To compile with SAS/C version 6, type: */
/* smake */
/* */
/* Revision history: */
/* V1.50 - Fixed a bug that caused DSound's window to have the wrong */
/* height in some instances. Also extended DSound's Workbench*/
/* support: DSound now recognizes a number of tool types */
/* which give the user the same level of control as when */
/* DSound is used from the Shell. */
/* July 18, 1994 */
/* V1.40 - Fixed a bug that caused slowdowns with floptical drives, */
/* added some Workbench support (a project with "DSound" as */
/* its default tool can now be run by double-clicking on its */
/* icon), and added an ARexx port so now one can quit DSound */
/* via an ARexx command. In addition, DSound is no longer */
/* pure (i.e. can not be made resident), due to conflicts */
/* with MinRexx. */
/* July 2, 1994 */
/* V1.31 - Fixed some bugs that caused some samples (esp. ones */
/* without a CHAN chunk) to not play. */
/* March 6, 1994 */
/* V1.30 - DSound now displays the name of the sound sample being */
/* played, the number of seconds of the sample that have been */
/* played, and the total number of seconds in the sample. */
/* A bug that prevent DSound from being aborted from the */
/* window when a stereo sample is played has also been fixed. */
/* July 17, 1993 */
/* V1.20 - Added the ability to stop DSound by typing CTRL-C, and */
/* added the switch '-w', which keeps the DSound window from */
/* opening. */
/* August 23, 1992 */
/* V1.10 - Added the ability to play a sound sample repeatedly (in a */
/* loop). */
/* July 11, 1992 */
/* V1.00 - Added a new module (Mem.c) which allows a sample to be */
/* loaded entirely into memory, so samples can be played from */
/* floppy disk without first copying to a hard or RAM drive. */
/* DSound also can now play a single channel of a stereo */
/* out of two speakers. The small window, used to let the */
/* user abort a playing sample, as been redone (DSound also */
/* now responds instantly when the user clicks on the Close */
/* gadget). DSound now checks a given 8SVX sample to make */
/* sure that it is actually a valid sample. Finally, DSound */
/* has been made pure (residentiable). */
/* Second release (April 16, 1992) */
/* V0.94a - Can now play a mono sample out of both speakers at the */
/* same time (using the -2 switch). */
/* March 27, 1992 (a little later) */
/* V0.93a - Now handles stereo sound samples. Either the right or */
/* left, or both, stereo channels can be played. Also split */
/* off the code that actually plays the sound sample into a */
/* separate source file (Play.c). */
/* March 27, 1992 */
/* V0.92a - Now gets the length of the sound sample from the head of */
/* the BODY chunk, instead of the VHDR (a workaround to a bug */
/* in the Perfect Sound software that would sometimes store */
/* an incorrect length in the VHDR chunk of a sound sample). */
/* November 4, 1991 */
/* V0.91a - First release (September 11, 1991) */
/**************************************************************************/
#include <exec/types.h>
#include <exec/exec.h>
#include <devices/audio.h>
#include <dos/dos.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <graphics/gfxbase.h>
#include <workbench/startup.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "dsound.h"
#include "arexx.h"
#include "minrexx.h"
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/icon.h>
#include <pragmas/intuition_pragmas.h>
#include <pragmas/graphics_pragmas.h>
#include <pragmas/exec_pragmas.h>
#include <pragmas/dos_pragmas.h>
char filename[256];
#define DEF_BUF_SIZE 0xFFFFFFFF
void InterpretArgs(int argc,char *argv[]);
void InterpretWBArgs(struct WBArg *wbArgs);
BOOL LoopAndNoWindow_WB(void);
void showAboutWindow(void);
BOOL noFilter=FALSE;
UBYTE volume=0;
UWORD speed=0;
ULONG bufSize=DEF_BUF_SIZE;
void filter_on(void);
void filter_off(void);
char *getDoubleDigit(unsigned int value,char *buf);
char *version="$VER: DSound V1.50 (18.7.94)";
char *copyright="Copyright 1991-1994 by Dave Schreiber, All Rights Reserved";
extern struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase=NULL;
extern struct Library *IconBase;
struct Window *window=NULL;
BPTR file=NULL;
channel audioChannel=UNSPECIFIED;
BOOL bothChan=FALSE;
BOOL readAll=FALSE;
BOOL loop=FALSE;
BOOL titleBarName=TRUE;
BOOL titleBarTime=TRUE;
/*The window definition*/
struct NewWindow newWindow = {
0,0,
60,56,
0,1,
CLOSEWINDOW,
SMART_REFRESH|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE,
NULL,
NULL,
"DSound V1.50",
NULL,
NULL,
5,5,
640,200,
WBENCHSCREEN
};
/*This determines whether or not the window will be opened*/
BOOL openTheWdw=TRUE;
ULONG signalMask=SIGBREAKF_CTRL_C;
struct TextFont *titleBarFont=NULL;
long arexxSigBit=0;
extern struct WBStartup *WBenchMsg;
main(int argc,char *argv[])
{
struct Voice8Header vhdr;
UBYTE foo2[5];
UBYTE foo[5];
ULONG chan;
ULONG sampleLength;
ULONG lock;
ULONG titleLength,nameLength,timeLength,colonLength,finalDelta;
char *chanStr;
filename[0]=NULL;
/*If run from the CLI*/
if(WBenchMsg==NULL)
{
/*Get and interpret the command-line arguments*/
InterpretArgs(argc,argv);
}
else
{
if(WBenchMsg->sm_NumArgs>0)
InterpretWBArgs(&WBenchMsg->sm_ArgList[0]);
if(WBenchMsg->sm_NumArgs>1)
{
CurrentDir(WBenchMsg->sm_ArgList[1].wa_Lock);
InterpretWBArgs(&WBenchMsg->sm_ArgList[1]);
if(loop && openTheWdw==FALSE)
if(!LoopAndNoWindow_WB())
exit(0);
strcpy(filename,WBenchMsg->sm_ArgList[1].wa_Name);
}
else
{
showAboutWindow();
exit(0);
}
}
/*Exit if there was no sound sample specified*/
if(filename[0]==NULL)
{
WriteMsg("Please specify the name of a sound sample\n");
cleanup(75);
}
/*Open the file*/
file=Open(filename,MODE_OLDFILE);
if(file==NULL)
{
WriteMsg("Couldn't open the file\n");
cleanup(100);
}
arexxSigBit=initRexxPort();
/*If the user hasn't told us not to open the window*/
if(openTheWdw)
{
char temp[256];
int yDelta=0;
/*Open libraries*/
GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",0L);
if(GfxBase==NULL || IntuitionBase==NULL)
{
WriteMsg("A shared library could not be opened\n");
cleanup(50);
}
/*Get the size of the title bar font in a rather illegal way */
/*Note: programmers at C= should put a GetDefTitleBarFontHeight() */
/*function into Intuition before complaining to me about the following*/
/*code. */
lock=LockIBase(0L);
newWindow.Height=IntuitionBase->ActiveScreen->Font->ta_YSize+3;
UnlockIBase(lock);
window=OpenWindow(&newWindow);
if(window->WScreen->Font->ta_YSize+3!=window->Height)
yDelta=window->WScreen->Font->ta_YSize+3-window->Height;
/* SizeWindow(window,0,window->WScreen->Font->ta_YSize+3-window->Height);*/
if(window==NULL)
cleanup(110);
signalMask|=1<<window->UserPort->mp_SigBit;
titleBarFont=OpenFont(IntuitionBase->ActiveScreen->Font);
if(titleBarFont==NULL)
cleanup(115);
SetFont(window->RPort,titleBarFont);
finalDelta=titleLength=TextLength(window->RPort,"DSound V1.50",12);
colonLength=TextLength(window->RPort,": ",3);
if(titleBarTime==FALSE)
{
timeLength=0;
if(titleBarName==FALSE)
colonLength=0;
}
else
timeLength=TextLength(window->RPort,"(00:00/00:00) ",14);
if(titleBarName==FALSE)
nameLength=0;
else
{
strcpy(temp,"\"\"");
strcat(temp,filename);
nameLength=TextLength(window->RPort,temp,strlen(temp));
}
if(60+finalDelta+nameLength+colonLength+timeLength >= window->WScreen->Width)
{
titleBarName=FALSE;
if(60+finalDelta+colonLength+timeLength >= window->WScreen->Width)
{
titleBarTime=FALSE;
if(60+titleLength >= window->WScreen->Width)
cleanup(199);
}
else
finalDelta+=(colonLength+timeLength);
}
else
finalDelta+=(colonLength+timeLength+nameLength);
SizeWindow(window,finalDelta,yDelta);
}
/*Read the header*/
Read(file,foo,4);
Seek(file,4,OFFSET_CURRENT);
Read(file,foo2,4);
foo[4]=foo2[4]=NULL;
/*Check the header's validity, more or less*/
if((strcmp(foo,"FORM")!=0) || (strcmp(foo2,"8SVX")!=0))
{
WriteMsg("Not a valid IFF 8SVX sound sample file.\n");
cleanup(120);
}
if(strcmp(FindChunk(file,"VHDR"),"VHDR")!=0)
{
WriteMsg("Couldn't find the 8SVX header (VHDR).\n");
cleanup(130);
}
/*Skip past the chunk size*/
Seek(file,4,OFFSET_CURRENT);
/*Get the VHDR*/
Read(file,&vhdr,sizeof(struct Voice8Header));
/*If no buffer size was specified, use a buffer that can hold 1 second*/
/*of sound*/
if(bufSize==0xFFFFFFFF)
bufSize=(vhdr.samplesPerSec+1)&(~1);
/*Check for compression*/
if(vhdr.sCompression!=0)
{
WriteMsg("Can't play a compressed sample!\n");
cleanup(400);
}
/*Get the CHAN chunk (which will tell us if the sample is stereo, or,*/
/*if it is mono, which speaker it should be played out of*/
chanStr=FindChunk(file,"CHAN");
if(strcmp(chanStr,"CHAN")==0)
{
/*Skip past chunk size*/
Seek(file,4,OFFSET_CURRENT);
Read(file,&chan,sizeof(long));
/*The information we're looking for consists of one longword*/
switch(chan)
{
case 2: /*Mono sample, left speaker*/
if(bothChan)
/*Play out of both channels if -2 used*/
audioChannel=MONO_BOTH;
else
if(audioChannel==UNSPECIFIED)
audioChannel=MONO_LEFT;
break;
case 4: /*Mono sample, right speaker*/
if(bothChan)
/*Play out of both channels if -2 used*/
audioChannel=MONO_BOTH;
else
if(audioChannel==UNSPECIFIED)
audioChannel=MONO_RIGHT;
break;
case 6: /*Stereo*/
switch(audioChannel)
{
/*This reconciles a user's choice with the fact that the*/
/*sample is in stereo*/
/*Play left stereo channel*/
case MONO_LEFT:
if(bothChan)
audioChannel=STEREO_LEFT_BOTH;
else
audioChannel=STEREO_LEFT;
break;
/*Play right stereo channel*/
case MONO_RIGHT:
if(bothChan)
audioChannel=STEREO_RIGHT_BOTH;
else
audioChannel=STEREO_RIGHT;
break;
/*Play both channels*/
case UNSPECIFIED:
audioChannel=STEREO;
break;
}
break;
}
}
else
{
chan=0;
if(bothChan)
audioChannel=MONO_BOTH;
}
/*Find the start of the BODY chunk*/
chanStr=FindChunk(file,"BODY");
if(strcmp(chanStr,"BODY")!=0)
{
WriteMsg("Couldn't find body of sample.\n");
cleanup(140);
}
if(noFilter)
filter_off();
/*Get the length of the sample*/
Read(file,(char *)&sampleLength,4);
SetSignal(0,0);
/*Play the sample by choosing the appropriate player function*/
switch(audioChannel)
{
case MONO_LEFT:
case MONO_RIGHT:
case UNSPECIFIED:
/*Simple mono playback*/
playMonoSample(file,audioChannel,&vhdr,sampleLength);
break;
case MONO_BOTH:
/*Mono playback using both speakers*/
playMonoTwice(file,audioChannel,&vhdr,sampleLength);
break;
case STEREO_RIGHT:
/*Right stereo channel*/
audioChannel=MONO_RIGHT;
Seek(file,sampleLength/2,OFFSET_CURRENT);
playMonoSample(file,audioChannel,&vhdr,sampleLength/2);
break;
case STEREO_RIGHT_BOTH:
/*Right stereo channel out of both speakers*/
audioChannel=MONO_RIGHT;
Seek(file,sampleLength/2,OFFSET_CURRENT);
playMonoTwice(file,audioChannel,&vhdr,sampleLength/2);
break;
case STEREO_LEFT:
/*Left stereo channel*/
audioChannel=MONO_LEFT;
playMonoSample(file,audioChannel,&vhdr,sampleLength/2);
break;
case STEREO_LEFT_BOTH:
/*Left stereo channel out of both speakers*/
audioChannel=MONO_LEFT;
playMonoTwice(file,audioChannel,&vhdr,sampleLength/2);
break;
case STEREO:
/*Stereo sample (both channels)*/
playStereoSample(file,audioChannel,&vhdr,sampleLength/2,filename);
break;
}
if(noFilter)
filter_on();
/*Free allocated resources and exit*/
cleanup(0);
}
/* Get an audio channel */
struct IOAudio *GetAudioChannel(ULONG bufferSize,UBYTE *allocationMap)
{
struct IOAudio *aIOB;
void *audioBuf;
struct Port *aPort;
aPort=(struct Port *)CreatePort("dsound",0);
if(aPort==NULL)
return(NULL);
/* Allocate the chip memory buffer for the channel */
audioBuf=(void *)AllocMem(bufferSize,MEMF_CHIP);
if(audioBuf==NULL)
{
DeletePort((struct MsgPort *)aPort);
return(NULL);
}
/* Allocate an IOAudio structure*/
aIOB=(struct IOAudio *)AllocMem(sizeof(struct IOAudio),MEMF_PUBLIC|MEMF_CLEAR);
if(aIOB==NULL)
{
DeletePort((struct MsgPort *)aPort);
FreeMem(audioBuf,bufferSize);
return(NULL);
}
/* Set up the IOAudio to allocate the command channel */
aIOB->ioa_Request.io_Message.mn_Node.ln_Pri=0;
aIOB->ioa_Request.io_Message.mn_ReplyPort=(struct MsgPort *)aPort;
aIOB->ioa_Data=allocationMap;
aIOB->ioa_Length=4;
aIOB->ioa_Request.io_Command=ADCMD_ALLOCATE;
/*Open the audio device*/
OpenDevice("audio.device",0,(struct IORequest *)aIOB,0);
if(aIOB->ioa_AllocKey==0)
{ /*There was an error*/
DeletePort((struct MsgPort *)aPort);
FreeMem(audioBuf,bufferSize);
FreeMem(aIOB,sizeof(struct IOAudio));
return(NULL);
}
else
{
/* Set up the IOAudio for writes */
aIOB->ioa_Request.io_Command=CMD_WRITE;
aIOB->ioa_Request.io_Flags=ADIOF_PERVOL;
aIOB->ioa_Data=audioBuf;
aIOB->ioa_Length=bufferSize;
return(aIOB);
}
}
/* Free an allocated audio channel */
void FreeAudioChannel(struct IOAudio *aIOB)
{
if(aIOB==NULL)
return;
/* Free the audi obuffer */
if(aIOB->ioa_Data!=NULL)
FreeMem(aIOB->ioa_Data,aIOB->ioa_Length);
/* Free the audio channel */
aIOB->ioa_Request.io_Command=ADCMD_FREE;
BeginIO((struct IORequest *)aIOB);
WaitIO((struct IORequest *)aIOB);
DeletePort(aIOB->ioa_Request.io_Message.mn_ReplyPort);
/* Close the audio channel */
CloseDevice((struct IORequest *)aIOB);
/* Free the IOAudio structure */
FreeMem(aIOB,sizeof(struct IOAudio));
return;
}
/* Initialize an IOAudio's volume, period, and set the number of cycles */
/* to one */
void InitAudioChannel(struct IOAudio *aIOB,UWORD volume,UWORD period)
{
aIOB->ioa_Period=period;
aIOB->ioa_Volume=volume;
aIOB->ioa_Cycles=1;
return;
}
/* Duplicate an IOAudio structure */
struct IOAudio *DuplicateAudioChannel(struct IOAudio *OrigIOB)
{
struct IOAudio *aIOB;
void *audioBuf;
if(OrigIOB==NULL)
return(NULL);
/* Allocate the alternate buffer */
audioBuf=(void *)AllocMem(OrigIOB->ioa_Length,MEMF_CHIP);
if(audioBuf==NULL)
return(NULL);
/*Allocate the IOAudio structure*/
aIOB=(struct IOAudio *)AllocMem(sizeof(struct IOAudio),MEMF_PUBLIC|MEMF_CLEAR);
if(aIOB==NULL)
{
FreeMem(audioBuf,OrigIOB->ioa_Length);
return(NULL);
}
/*Copy the original IOAudio's contents to the new one*/
CopyMem(OrigIOB,aIOB,sizeof(struct IOAudio));
/*Except for the buffer pointer, of course*/
aIOB->ioa_Data=audioBuf;
return(aIOB);
}
/*Delete a duplicated IOAudio*/
void DeleteDuplication(struct IOAudio *aIOB)
{
if(aIOB != NULL)
{
/* Free the memory for the buffer and IOAudio */
if(aIOB->ioa_Data != NULL)
FreeMem(aIOB->ioa_Data,aIOB->ioa_Length);
FreeMem(aIOB,sizeof(struct IOAudio));
}
return;
}
/* Load an IOAudio's buffer from an open file */
ULONG LoadAudioBuffer(BPTR file,struct IOAudio *aIOB,ULONG toRead)
{
if(toRead==0)
return(0);
if(file==0L)
getLeft(aIOB->ioa_Data);
else if(file==4L)
getRight(aIOB->ioa_Data);
else
aIOB->ioa_Length=Read(file,aIOB->ioa_Data,toRead);
return(aIOB->ioa_Length);
}
/*Find the beginning of an IFF chunk. This routine will search for that*/
/*chunk's name, and if found, will leave the file cursor at the chunk size*/
/*field. If the chunk isn't found, the file cursor will be left at the*/
/*size field of the BODY chunk, if there was one*/
char *FindChunk(BPTR file,char *string)
{
long len,actLen;
int origPos;
static char buf[5];
buf[4]=NULL;
/* If we cannot find the chunk, seek the file pointer back to the */
/* place it started at */
origPos=Seek(file,0,OFFSET_CURRENT);
actLen=Read(file,buf,4);
while(strcmp(string,buf)!=0 && strcmp(buf,"BODY")!=0 && actLen > 0)
{
Read(file,(char *)&len,4);
len=(len+1) & (~1);
Seek(file,len,OFFSET_CURRENT);
actLen=Read(file,buf,4);
}
if(strcmp(string,buf)!=0)
Seek(file,origPos,OFFSET_BEGINNING);
return(buf);
}
/* Interpret the command line arguments */
void InterpretArgs(int argc,char *argv[])
{
int i;
for(i=1;i<argc;i++)
{
if(argv[i][0]=='-')
switch(argv[i][1])
{
/*Deactivate title bar filename*/
case 'n':
case 'N':
titleBarName=FALSE;
break;
/*Deactivate title bar time*/
case 't':
case 'T':
titleBarTime=FALSE;
break;
/* Read the entire sample into memory before playing */
case 'm':
case 'M':
readAll=TRUE;
break;
/* Use the left channel */
case 'l':
case 'L':
audioChannel=MONO_LEFT;
break;
/* Use the right channel */
case 'r':
case 'R':
audioChannel=MONO_RIGHT;
break;
/*Play a mono sample out of both speakers*/
case '2':
bothChan=TRUE;
break;
/* Switch off the low-pass filter while the sample is playing */
case 'f':
case 'F':
noFilter=TRUE;
break;
/* Play a sample at a given speed */
case 's':
case 'S':
speed=atol(&argv[i][2]);
if(speed > 28000)
speed=0;
break;
/* The volume at which the sample should be played */
case 'v':
case 'V':
volume=atol(&argv[i][2]);
if(volume > 64)
volume=0;
break;
/* The size of the chip RAM buffers */
case 'b':
case 'B':
bufSize=(atol(&argv[i][2])+1)&(~1);
if(bufSize==0)
bufSize=DEF_BUF_SIZE;
break;
/* Loop the sample */
case 'o':
case 'O':
loop=TRUE;
break;
case 'w':
case 'W':
openTheWdw=FALSE;
break;
}
else if(argv[i][0]=='?')
{
/*On-line help*/
WriteMsg("DSound V1.50 ©1991-1994 by Dave Schreiber\n");
WriteMsg("Usage:\n");
WriteMsg(" DSound <options> <filename>\n");
WriteMsg("Where the options are:\n");
WriteMsg(" -l -- Play the sample using the left speaker\n");
WriteMsg(" -r -- Play the sample using the right speaker\n");
WriteMsg(" -2 -- Play the sample using both speakers\n");
WriteMsg(" -f -- Shut off the low-pass filter\n");
WriteMsg(" -m -- Load the entire sample into memory\n");
WriteMsg(" -o -- Play the sample continuously (loop)\n");
WriteMsg(" -w -- Do not open the DSound window\n");
WriteMsg(" -n -- Do not show the sample name in the window\n");
WriteMsg(" -t -- Do not show the sample times in the window\n");
WriteMsg(" -s<speed> -- Play the sample at the given speed (samples/sec)\n");
WriteMsg(" -v<volume> -- Play the sample at the given volume (0-64)\n");
WriteMsg(" -b<bufsize> -- Use a buffer of size <bufsize> (default is 30K)\n");
exit(0);
}
else /*Otherwise, the argument is a filename */
strcpy(filename,argv[i]);
}
}
/* Interpret Workbench arguments */
void InterpretWBArgs(struct WBArg *wbArgs)
{
struct DiskObject *myIcon;
if(wbArgs->wa_Name!=NULL && (myIcon=GetDiskObject(wbArgs->wa_Name))!=NULL)
{
char *val;
char **toolArray=(char **)myIcon->do_ToolTypes;
if((val=FindToolType(toolArray,"PLAYWINDOW"))!=NULL)
{
if(MatchToolValue(val,"YES"))
openTheWdw=TRUE;
else if(MatchToolValue(val,"NO"))
openTheWdw=FALSE;
}
if((val=FindToolType(toolArray,"TITLETIME"))!=NULL)
{
if(MatchToolValue(val,"YES"))
titleBarTime=TRUE;
else if(MatchToolValue(val,"NO"))
titleBarTime=FALSE;
}
if((val=FindToolType(toolArray,"TITLENAME"))!=NULL)
{
if(MatchToolValue(val,"YES"))
titleBarName=TRUE;
else if(MatchToolValue(val,"NO"))
titleBarName=FALSE;
}
if((val=FindToolType(toolArray,"READALL"))!=NULL)
{
if(MatchToolValue(val,"YES"))
readAll=TRUE;
else if(MatchToolValue(val,"NO"))
readAll=FALSE;
}
if((val=FindToolType(toolArray,"SPEAKER"))!=NULL)
{
if(MatchToolValue(val,"LEFT"))
{
audioChannel=MONO_LEFT;
bothChan=FALSE;
}
if(MatchToolValue(val,"RIGHT"))
{
audioChannel=MONO_RIGHT;
bothChan=FALSE;
}
if(MatchToolValue(val,"BOTH"))
bothChan=TRUE;
if(MatchToolValue(val,"DONTCARE"))
{
audioChannel=UNSPECIFIED;
bothChan=FALSE;
}
}
if((val=FindToolType(toolArray,"FILTER"))!=NULL)
{
if(MatchToolValue(val,"YES"))
noFilter=FALSE;
else if(MatchToolValue(val,"NO"))
noFilter=TRUE;
}
if((val=FindToolType(toolArray,"LOOP"))!=NULL)
{
if(MatchToolValue(val,"YES"))
loop=TRUE;
else if(MatchToolValue(val,"NO"))
loop=FALSE;
}
if((val=FindToolType(toolArray,"SPEED"))!=NULL)
{
speed=atoi(val);
if(speed > 28000)
speed=0;
}
if((val=FindToolType(toolArray,"VOLUME"))!=NULL)
{
volume=atol(val);
if(volume > 64)
volume=0;
}
if((val=FindToolType(toolArray,"BUFSIZE"))!=NULL)
{
bufSize=atol(val);
if(bufSize==0)
bufSize=DEF_BUF_SIZE;
}
}
}
/*Update the sample information in the DSound window's title bar*/
/*This information can included the name of the sample, along with*/
/*its length and amount played (both in seconds)*/
void updateSampleInfo(unsigned int currentPos,unsigned int length,
unsigned int sampleRate)
{
unsigned int currentSeconds,currentMinutes,totalSeconds,totalMinutes;
static char windowTitle[256];
char tempBuf[4][4];
static BOOL nameAlreadyDisplayed=FALSE;
/*If the user wants neither the name nor time printed, do nothing*/
/*Also do nothing if the window isn't open*/
if((titleBarTime==FALSE && titleBarName==FALSE) || window==NULL)
return;
/*Return if the user just wanted the name displayed, and it has been*/
if(titleBarTime==FALSE && nameAlreadyDisplayed==TRUE)
return;
/*Beginning of the title*/
strcpy(windowTitle,"DSound V1.50: ");
/*If the user wants the sample name displayed, put it in the buffer*/
if(titleBarName)
{
nameAlreadyDisplayed=TRUE;
sprintf(&windowTitle[strlen(windowTitle)],"\"%s\" ",filename);
/*The name has been (or will be shortly) displayed, so don't */
/*update it again if you don't have to */
nameAlreadyDisplayed=TRUE;
}
/*Likewise for the time left and the total time*/
if(titleBarTime)
{
/*Get the total time*/
totalSeconds=(length)/sampleRate;
totalMinutes=totalSeconds/60;
totalSeconds-=totalMinutes*60;
/*Get the current time*/
currentSeconds=(currentPos)/sampleRate;
currentMinutes=currentSeconds/60;
currentSeconds-=currentMinutes*60;
/*Create the string that holds the time, and put it in the*/
/*title bar buffer*/
sprintf(&windowTitle[strlen(windowTitle)],"(%s:%s/%s:%s)",
getDoubleDigit(currentMinutes,tempBuf[0]),
getDoubleDigit(currentSeconds,tempBuf[1]),
getDoubleDigit(totalMinutes,tempBuf[2]),
getDoubleDigit(totalSeconds,tempBuf[3]));
}
Forbid();
/*Make sure that the screen isn't locked (e.g. holding down the*/
/*RMB will lock the screen), so that DSound will continue to */
/*play even if it can't update the title bar*/
if(window->WScreen->LayerInfo.Lock.ss_NestCount==0)
SetWindowTitles(window,windowTitle,NULL);
Permit();
return;
}
char *getDoubleDigit(unsigned int value,char *buf)
{
if(value<10)
sprintf(buf,"0%d",value);
else
sprintf(buf,"%d",value);
return(buf);
}
/*Switch on the low-pass filter */
void filter_on()
{
*((char *)0x0bfe001)&=0xFD;
}
/*Switch off the low-pass filter*/
void filter_off()
{
*((char *)0x0bfe001)|=0x02;
}
struct EasyStruct erError1Line=
{
sizeof(struct EasyStruct),
0,
"Program error: DSound",
"%s",
"Ok"
};
/*Write a message to the CLI*/
void WriteMsg(char *errMsg)
{
if(WBenchMsg==NULL)
Write(Output(),errMsg,strlen(errMsg));
else
{
char tmpBuf[256];
int len=strlen(errMsg);
strcpy(tmpBuf,errMsg);
if(tmpBuf[len-1]=='\n')
tmpBuf[len-1]=0;
EasyRequest(NULL,&erError1Line,NULL,tmpBuf);
}
}
struct EasyStruct dontDoThat=
{
sizeof(struct EasyStruct),
0,
"Program request: DSound",
"Warning!\nWith looping enabled and\nno window, DSound will be\ndifficult to stop.",
"OK|Cancel"
};
BOOL LoopAndNoWindow_WB(void)
{
int result;
result=EasyRequest(NULL,&dontDoThat,NULL,NULL);
if(result==1)
return TRUE;
else
return FALSE;
}
struct EasyStruct aboutDSound=
{
sizeof(struct EasyStruct),
0,
"About DSound...",
"DSound V1.50\nJuly 18, 1994\n©1991-1994 by Dave Schreiber\nAll Rights Reserved.",
"OK"
};
void showAboutWindow(void)
{
EasyRequest(NULL,&aboutDSound,NULL,NULL);
return;
}
/*Take a file handle and that handle's filename, and open that file again*/
/*The position in the second file in set to the position in the first */
/*file (so that the two file handles are essentially identical)*/
/*This requires that the first file was opened in a shared mode, like */
/*MODE_OLDFILE*/
BPTR dupFileHandle(BPTR origFile,char *filename)
{
BPTR dupFile;
dupFile=Open(filename,MODE_OLDFILE);
if(dupFile==NULL)
return(NULL);
Seek(dupFile,getPosInFile(origFile),OFFSET_BEGINNING);
return(dupFile);
}
/*Get the current position in a file*/
ULONG getPosInFile(BPTR file)
{
LONG position;
position=Seek(file,0,OFFSET_CURRENT);
return((ULONG)position);
}
/* Free allocated resources */
void cleanup(int err)
{
if(arexxSigBit!=0)
dnRexxPort();
/*If the entire sample was read into memory, this will delete whatever*/
/*part of the sample still remains in memory*/
deleteLeft();
deleteRight();
if(file!=NULL)
Close(file);
if(window!=NULL)
CloseWindow(window);
if(titleBarFont!=NULL)
CloseFont(titleBarFont);
if(GfxBase!=NULL)
CloseLibrary((struct Library *)GfxBase);
exit(err);
}
#ifdef LATTICE
int CXBRK(void) {return(0);}
int chkabort(void) {return(0);}
#endif
/*End of DSound.c*/